/*
    Dominate 3D - A cube-based game of life

    Copyright (C) 2007, Craig H. Miller (kidmosey@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "util.h"

#include <sys/stat.h>
#include <fstream>

int CheckReadStatus(SOCKET sockfd)
{
    timeval tv = { 0, 1 };
    fd_set serverSet = { 1, { sockfd } };

    return select(0, &serverSet, 0, 0, &tv);
}

std::string ftoa(float f)
{
    char result[32];

    sprintf(result, "%f", f);

    return result;
}

std::string itoa(int i)
{
    char result[32];

    sprintf(result, "%d", i);

    return result;
}

char *GetLastErrorStr(char *szErr)
{
    static char szMessage[1024];

    LPVOID lpMsgBuf;
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );

    if (szErr)
        wsprintf(szMessage, "%s: %s", szErr, (char *)lpMsgBuf);
    else
        wsprintf(szMessage, "%s", (char *)lpMsgBuf);

    LocalFree( lpMsgBuf );

    return szMessage;
}

char *CopyBinaryFile(const char *filename)
{
    static char result[MAX_PATH];
    tmpnam(result);

    HRSRC rc = FindResource(
        NULL,
        filename,
        RT_RCDATA
    );

    if (rc)
    {
        HGLOBAL resource = LoadResource(NULL, rc);

        char *data = (char *)LockResource(resource);
        if (!data)
        {
            printf("Unable to lock resource.\n");
            return 0;
        }

        size_t len = SizeofResource(NULL, rc);

        FILE *fp = fopen(result, "wb");
        fwrite(data, 1, len, fp);
        fclose(fp);
    }
    else
    {
        FILE *fout = fopen(result, "wb"),
             *fin  = fopen(filename, "rb");

        size_t len = 0;
        char buffer[1024 * 16];
        while ((len = fread(buffer, 1, sizeof(buffer), fin)) != 0)
            fwrite(buffer, 1, len, fout);

        fclose(fin);
        fclose(fout);
    }

    return result;
}

FILE *OpenBinaryFile(const char *filename)
{
    HRSRC rc = FindResource(
        NULL,
        filename,
        RT_RCDATA
    );

    if (rc)
    {
        HGLOBAL resource = LoadResource(NULL, rc);

        char *data = (char *)LockResource(resource);
        if (!data)
        {
            printf("Unable to lock resource.\n");
            return 0;
        }

        size_t len = SizeofResource(NULL, rc);

        FILE *fp = tmpfile();
        if (fwrite(data, 1, len, fp) != len)
        {
            fclose(fp);
            fp = 0;
        }
        else
        {
            fseek(fp, 0, SEEK_SET);
        }

        return fp;
    }
    else
    {
        return fopen(filename, "rb");
    }
}

int filesize(const char *fname)
{
    struct stat results;

    if (stat(fname, &results) == 0)
        return results.st_size;

    return -1;
}

std::string GetFileContents(const std::string &fname)
{
    std::string result;
    std::ifstream in(fname.c_str(), std::ios::in);

    int len = filesize(fname.c_str());
    if (len > 0)
    {
        char *buffer = new char[len + 1];

        in.read(buffer, len);
        buffer[len] = '\0';
        result = std::string(buffer);
        delete buffer;
    }

    return result;
}
